﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using EventBus.Extensions;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Ordering.API.Application.Commands;
using Ordering.API.Application.Queries;
using Ordering.API.Infrastructure.Services;
using Ordering.API.ViewModel;
using Paging;

namespace Ordering.API.Controllers
{
    [Route("api/v1/[controller]")]
    [Authorize(Roles = "administrator")]
    public class OrderController : ControllerBase
    {
        private readonly IIdentityService _identityService;
        private readonly ILogger<OrderController> _logger;
        private readonly IMediator _mediator;
        private readonly IOrderQueries _queries;
        public OrderController(IIdentityService identityService,
            ILogger<OrderController> logger,
            IMediator mediator,
            IOrderQueries queries)
        {
            _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
            _queries = queries ?? throw new ArgumentNullException(nameof(queries));
        }
        /// <summary>
        /// 获取订单
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("orders")]
        [ProducesResponseType(typeof(OrderSummaryModel), (int)HttpStatusCode.OK)]
        [ProducesResponseType(typeof(OrderModel), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<ActionResult<OrderSummaryModel>> GetOrdersAsync([FromBody]OrderFilter filter)
        {
            var orders = await _queries.GetOrderSummaryAsync(filter);
            return Ok(orders);
        }
        /// <summary>
        /// 预约订单
        /// </summary>
        /// <param name="order"></param>
        /// <param name="requestId"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("appointment")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> AppointmentOrder([FromBody]OrderRequest order, [FromHeader(Name = "x-requestid")] string requestId)
        {
            bool commandResult = false;
            if(Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
            {
                var customerCode = _identityService.GetUserIdentity();
                List<OrderItemDTO> orderItems = new List<OrderItemDTO>();
                AddressDTO address = new AddressDTO(order.Province,order.City,order.Area,order.Town,order.DetailedAddress,order.Latitude,order.Longitude,order.ExtendField);
                foreach(var item in order.OrderItems)
                {
                    orderItems.Add(new OrderItemDTO
                    {
                        ProductCode = item.ProductCode,
                        Num = item.Num,
                        ExpressCode = item.ExtendField2,
                        Remarks = item.Remark
                    });
                }
                OrderItemDTO items = new OrderItemDTO();
                CreateOrderCommand command = new CreateOrderCommand(customerCode, order.AppointmentTime, order.OrderType, order.Description, order.Remark, orderItems, address);
                var requestCreateOrder = new IdentifiedCommand<CreateOrderCommand, bool>(command, guid);
                _logger.LogInformation(
                    "----- Sending command: {CommandName} - ({@Command})",
                    requestCreateOrder.GetGenericTypeName(),
                    requestCreateOrder);
                commandResult = await _mediator.Send(requestCreateOrder);
            }
            if (!commandResult)
            {
                return BadRequest();
            }
            return Ok();
        }
        /// <summary>
        /// 取消订单
        /// </summary>
        /// <param name="order"></param>
        /// <param name="requestId"></param>
        /// <returns></returns>
        [HttpPut]
        [Route("cancel")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> CancelOrder([FromBody]CancelOrderRequest order, [FromHeader(Name = "x-requestid")] string requestId)
        {
            bool commandResult = false;
            if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
            {
                string userCode = _identityService.GetUserIdentity();
                CancelOrderCommand command = new CancelOrderCommand(order.OrderNO,order.Reason);
                var requestCancelOrder = new IdentifiedCommand<CancelOrderCommand, bool>(command, guid);
                _logger.LogInformation(
                    "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})",
                    requestCancelOrder.GetGenericTypeName(),
                    nameof(requestCancelOrder.Command.OrderNO),
                    requestCancelOrder.Command.OrderNO,
                    requestCancelOrder);
                commandResult = await _mediator.Send(requestCancelOrder);
            }
            if (!commandResult)
            {
                return BadRequest();
            }
            return Ok();
        }
        /// <summary>
        /// 接收订单
        /// </summary>
        /// <param name="requestId"></param>
        /// <returns></returns>
        [HttpPut]
        [Route("receive")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> ReceiveOrderAsync([FromBody] ReceiveOrderRequest request, [FromHeader(Name = "x-requestid")] string requestId)
        {
            bool commandResult = false;
            if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
            {
                string userCode = _identityService.GetUserIdentity();
                ReceiveOrderCommand command = new ReceiveOrderCommand(request.OrderNO, userCode);
                var requestCancelOrder = new IdentifiedCommand<ReceiveOrderCommand, bool>(command, guid);
                _logger.LogInformation(
                    "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})",
                    requestCancelOrder.GetGenericTypeName(),
                    nameof(requestCancelOrder.Command.OrderNO),
                    requestCancelOrder.Command.OrderNO,
                    requestCancelOrder);
                commandResult = await _mediator.Send(requestCancelOrder);
            }
            if (commandResult)
                return Ok();
            else
                return BadRequest();
        }
        /// <summary>
        /// 配送订单
        /// </summary>
        /// <param name=""></param>
        /// <param name="requestId"></param>
        /// <returns></returns>
        [HttpPut]
        [Route("delivery")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> DeliveryOrderAsync([FromBody] DeliveryOrderRequest request, [FromHeader(Name = "x-requestid")] string requestId)
        {
            bool commandResult = false;
            if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
            {
                string userCode = _identityService.GetUserIdentity();
                DeliveryOrderCommand command = new DeliveryOrderCommand(request.OrderNO, userCode);
                var requestCancelOrder = new IdentifiedCommand<DeliveryOrderCommand, bool>(command, guid);
                _logger.LogInformation(
                    "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})",
                    requestCancelOrder.GetGenericTypeName(),
                    nameof(requestCancelOrder.Command.OrderNO),
                    requestCancelOrder.Command.OrderNO,
                    requestCancelOrder);
                commandResult = await _mediator.Send(requestCancelOrder);
            }
            if (commandResult)
                return Ok();
            else
                return BadRequest();
        }
        /// <summary>
        /// 完成订单
        /// </summary>
        /// <param name=""></param>
        /// <param name="requestId"></param>
        /// <returns></returns>
        [HttpPut]
        [Route("completed")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> CompletedOrderAsync([FromBody] CompletedOrderRequest request, [FromHeader(Name = "x-requestid")] string requestId)
        {
            bool commandResult = false;
            if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
            {
                string userCode = _identityService.GetUserIdentity();
                CompletedOrderCommand command = new CompletedOrderCommand(request.OrderNO, userCode);
                var requestCancelOrder = new IdentifiedCommand<CompletedOrderCommand, bool>(command, guid);
                _logger.LogInformation(
                    "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})",
                    requestCancelOrder.GetGenericTypeName(),
                    nameof(requestCancelOrder.Command.OrderNO),
                    requestCancelOrder.Command.OrderNO,
                    requestCancelOrder);
                commandResult = await _mediator.Send(requestCancelOrder);
            }
            if (commandResult)
                return Ok();
            else
                return BadRequest();
        }

    }
}